// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: tianqiang

#pragma once

#include <string>

#include "coin2/exchange/base/api_base/asio_http_context.h"
#include "coin2/exchange/base/api_base/base_auth.h"
#include "coin2/exchange/base/api_util/api_signature.h"
#include "coin2/exchange/base/api_util/auth_key.h"
#include "coin2/exchange/base/api_util/url_params_builder.h"

namespace coin2::exchange::mexc::api_util_v3 {

class MexcRestAuth : public BaseRestAuth {
 public:
  explicit MexcRestAuth(
      const std::string& key_filepath,
      const std::string& host,
      const std::string& port,
      const std::string& bind_ip)
      : key_(AuthKey::FromFile(key_filepath)), host_(host), port_(port), bind_ip_(bind_ip) {
    headers_.emplace_back("X-MEXC-APIKEY", key_.access_key());
  }
  explicit MexcRestAuth(
      const std::string& key_filepath,
      const std::string& host,
      int32_t port,
      const std::string& bind_ip)
      : MexcRestAuth(key_filepath, host, std::to_string(port), bind_ip) {}

  AsioHttpContext* CreateRequestByGetWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override;
  AsioHttpContext* CreateRequestByPostWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override;
  AsioHttpContext* CreateRequestByDeleteWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override;
  AsioHttpContext* CreateRequestByPutWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override;

 private:
  std::string GetSignature(const std::string& params) {
    return ApiSignatureUtil::GetSignatureByHexHmacSHA256(params, key_.secret_key());
  }

  std::string GetUrl(const std::string& address, UrlParamsBuilder* builder);

 protected:
  AuthKey key_;
  std::string host_;
  std::string port_;
  std::string bind_ip_;
  std::vector<std::pair<std::string, std::string>> headers_;
};

}  // namespace coin2::exchange::mexc::api_util_v3
